View Javadoc
1   package org.apache.maven.surefire.junitcore;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
23  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
24  import org.apache.maven.surefire.report.RunListener;
25  import org.apache.maven.surefire.report.SimpleReportEntry;
26  import org.apache.maven.surefire.testset.TestSetFailedException;
27  import org.junit.runner.Description;
28  import org.junit.runner.Result;
29  import org.junit.runner.notification.Failure;
30  
31  /**
32   * A class to be used when there is no JUnit parallelism (methods or/and class). This allow to workaround JUnit
33   * limitation a la Junit4 provider. Specifically, we can redirect properly the output even if we don't have class
34   * demarcation in JUnit. It works when if there is a JVM instance per test run, i.e. with forkMode=always or perthread.
35   */
36  public class NonConcurrentRunListener
37      extends JUnit4RunListener
38      implements ConsoleOutputReceiver
39  {
40      private Description currentTestSetDescription;
41  
42      private Description lastFinishedDescription;
43  
44      public NonConcurrentRunListener( RunListener reporter )
45          throws TestSetFailedException
46      {
47          super( reporter );
48      }
49  
50      public synchronized void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
51      {
52          // We can write immediately: no parallelism and a single class.
53          ( (ConsoleOutputReceiver) reporter ).writeTestOutput( buf, off, len, stdout );
54      }
55  
56      protected SimpleReportEntry createReportEntry( Description description )
57      {
58          return new SimpleReportEntry( extractDescriptionClassName( description ), description.getDisplayName() );
59      }
60  
61      protected SimpleReportEntry createReportEntryForTestSet( Description description )
62      {
63          String testClassName = extractDescriptionClassName( description );
64          return new SimpleReportEntry( testClassName, testClassName );
65      }
66  
67      @Override
68      protected String extractDescriptionClassName( Description description )
69      {
70          return description.getClassName();
71      }
72  
73      @Override
74      protected String extractDescriptionMethodName( Description description )
75      {
76          return description.getMethodName();
77      }
78  
79      @Override
80      public void testStarted( Description description )
81          throws Exception
82      {
83          finishLastTestSetIfNecessary( description );
84          super.testStarted( description );
85      }
86  
87      private void finishLastTestSetIfNecessary( Description description )
88      {
89          if ( describesNewTestSet( description ) )
90          {
91              currentTestSetDescription = description;
92              if ( lastFinishedDescription != null )
93              {
94                  reporter.testSetCompleted( createReportEntryForTestSet( lastFinishedDescription ) );
95                  lastFinishedDescription = null;
96              }
97              reporter.testSetStarting( createReportEntryForTestSet( description ) );
98          }
99      }
100 
101     private boolean describesNewTestSet( Description description )
102     {
103         if ( currentTestSetDescription != null )
104         {
105             if ( null != description.getTestClass() )
106             {
107                 return !description.getTestClass().equals( currentTestSetDescription.getTestClass() );
108             }
109             else if ( description.isSuite() )
110             {
111                 return description.getChildren().equals( currentTestSetDescription.getChildren() );
112             }
113 
114             return false;
115         }
116 
117         return true;
118     }
119 
120     @Override
121     public void testFinished( Description description )
122         throws Exception
123     {
124         super.testFinished( description );
125         lastFinishedDescription = description;
126     }
127 
128     @Override
129     public void testIgnored( Description description )
130         throws Exception
131     {
132         finishLastTestSetIfNecessary( description );
133 
134         super.testIgnored( description );
135         lastFinishedDescription = description;
136     }
137 
138     @Override
139     public void testFailure( Failure failure )
140         throws Exception
141     {
142         finishLastTestSetIfNecessary( failure.getDescription() );
143 
144         super.testFailure( failure );
145         lastFinishedDescription = failure.getDescription();
146     }
147 
148     @Override
149     public void testAssumptionFailure( Failure failure )
150     {
151         super.testAssumptionFailure( failure );
152         lastFinishedDescription = failure.getDescription();
153     }
154 
155     @Override
156     public void testRunStarted( Description description )
157         throws Exception
158     {
159     }
160 
161     @Override
162     public void testRunFinished( Result result )
163         throws Exception
164     {
165         if ( lastFinishedDescription != null )
166         {
167             reporter.testSetCompleted( createReportEntryForTestSet( lastFinishedDescription ) );
168             lastFinishedDescription = null;
169         }
170     }
171 }